﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace Liang.Util.DataBase
{
    public static class DataTableHelper
    {
        /// <summary>
        /// 根据架构表创建表
        /// </summary>
        /// <param name="schemaTable"></param>
        /// <returns></returns>
        public static DataTable CreateTableBySchemaTable(DataTable schemaTable)
        {
            DataTable dtReturn = new DataTable();
            foreach (DataRow row in schemaTable.Rows)
            {
                Type type = Liang.Util.DataBase.DataConvert.SqlTypeString2CSharpType((string)row["DataTypeName"]);
                dtReturn.Columns.Add(new DataColumn(row["ColumnName"].ToString(), type));
            }
            return dtReturn;
        }

        /// <summary>
        /// 根据架构表获取表列名
        /// </summary>
        /// <param name="schemaTable"></param>
        /// <returns></returns>
        public static List<string> GetColumnsBySchemaTable(DataTable schemaTable)
        {
            List<string> cols = new List<string>();

            foreach (DataRow row in schemaTable.Rows)
            {
                cols.Add(row["ColumnName"].ToString());
            }

            return cols;
        }

        /// <summary>
        /// 将DataGridView的数据转换为DataTable
        /// </summary>
        /// <param name="dgv"></param>
        /// <returns></returns>
        public static DataTable DataGridViewToTable(DataGridView dgv)
        {
            DataTable dt = new DataTable();
            for (int count = 0; count < dgv.Columns.Count; count++)
            {
                DataColumn dc = new DataColumn(dgv.Columns[count].Name.ToString());
                dt.Columns.Add(dc);
            }
            for (int count = 0; count < dgv.Rows.Count; count++)
            {
                DataRow dr = dt.NewRow();
                for (int countsub = 0; countsub < dgv.Columns.Count; countsub++)
                {
                    dr[countsub] = dgv.Rows[count].Cells[countsub].Value.ToString();
                }
                dt.Rows.Add(dr);
            }
            return dt;
        }

        /// <summary>    
        /// 转化一个DataTable    
        /// </summary>    
        /// <typeparam name="T"><peparam>    
        /// <param name="list"></param>    
        /// <returns></returns>    
        public static DataTable ToDataTable<T>(this IEnumerable<T> list) where T : class, new()
        {
            //创建属性的集合    
            List<PropertyInfo> pList = new List<PropertyInfo>();
            //获得反射的入口    

            Type type = typeof(T);
            DataTable dt = new DataTable();
            //把所有的public属性加入到集合 并添加DataTable的列    
            Array.ForEach<PropertyInfo>(type.GetProperties(), p => { pList.Add(p); dt.Columns.Add(p.Name, p.PropertyType); });
            foreach (var item in list)
            {
                //创建一个DataRow实例    
                DataRow row = dt.NewRow();
                //给row 赋值    
                pList.ForEach(p => row[p.Name] = p.GetValue(item, null));
                //加入到DataTable    
                dt.Rows.Add(row);
            }
            return dt;
        }

        /// <summary>
        /// DataSetToList
        /// </summary>
        /// <typeparam name="T">转换类型</typeparam>
        /// <param name="DataTable">数据源</param>
        /// <returns></returns>
        //public List<T> DataTableToList(DataTable table)
        //{
        //    //确认参数有效
        //    if (table == null)
        //        return null;
        //    List<T> list = new List<T>();
        //    for (int i = 0; i < table.Rows.Count; i++)
        //    {
        //        //创建泛型对象
        //        T _t = Activator.CreateInstance<T>();
        //        //获取对象所有属性
        //        PropertyInfo[] propertyInfo = _t.GetType().GetProperties();
        //        for (int j = 0; j < table.Columns.Count; j++)
        //        {
        //            foreach (PropertyInfo info in propertyInfo)
        //            {
        //                //属性名称和列名相同时赋值
        //                if (table.Columns[j].ColumnName.ToUpper().Equals(info.Name.ToUpper()))
        //                {
        //                    if (table.Rows[i][j] != DBNull.Value)
        //                    {
        //                        info.SetValue(_t, table.Rows[i][j], null);
        //                    }
        //                    else
        //                    {
        //                        info.SetValue(_t, null, null);
        //                    }
        //                    break;
        //                }
        //            }
        //        }
        //        list.Add(_t);
        //    }
        //    return list;
        //}

        /// <summary>    
        /// DataTable 转换为List 集合    
        /// </summary>    
        /// <typeparam name="TResult">类型<peparam>    
        /// <param name="dt">DataTable</param>    
        /// <returns></returns>    
        public static List<T> ToList<T>(this DataTable dt) where T : class, new()
        {
            //创建一个属性的列表    
            List<PropertyInfo> prlist = new List<PropertyInfo>();
            //获取TResult的类型实例  反射的入口    
            Type t = typeof(T);
            //获得TResult 的所有的Public 属性 并找出TResult属性和DataTable的列名称相同的属性(PropertyInfo) 并加入到属性列表     
            Array.ForEach<PropertyInfo>(t.GetProperties(), p => { if (dt.Columns.IndexOf(p.Name) != -1) prlist.Add(p); });

            //创建返回的集合    
            List<T> oblist = new List<T>();
            foreach (DataRow row in dt.Rows)
            {
                //创建TResult的实例    
                T ob = new T();
                //到对应的数据  并赋值    
                prlist.ForEach(p => { if (row[p.Name] != DBNull.Value) p.SetValue(ob, row[p.Name], null); });
                //放入到返回的集合中.    
                oblist.Add(ob);
            }
            return oblist;
        }
    }
}
